const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// 压缩css
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')

// 为了让postcss生效而设置的环境变量，配合 browserslist 的哪个环境。
process.env.NODE_ENV = 'production'

// 复用loader
const commonCssLoader = [
  MiniCssExtractPlugin.loader,
  'css-loader',
  {
    // 解决css浏览器兼容性的问题
    // 需要在package.json中定义 browserslist
    loader: 'postcss-loader',
    // 新的方法
    options: {
      postcssOptions: {
        config: resolve(__dirname, './postcss.config.js'),
      },
    },
  },
]

/**
 * 生产环境搭建
 */
module.exports = {
  entry: resolve(__dirname, './src/js/index.js'),
  output: {
    filename: 'js/built.js',
    // 输出到的文件夹
    path: resolve(__dirname, 'build'),
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [...commonCssLoader],
      },
      {
        test: /\.less$/,
        use: [...commonCssLoader, 'less-loader'],
      },
      /**
       * 一般，一个文件只能被一个loader处理。
       * 如果被多个文件处理，一定要注意loader的执行顺序。
       * 先执行eslint，再执行babel。
       */
      {
        // 检查js语法
        // 在package.json中添加eslintConfig->airbnb规则
        test: /\.js$/,
        exclude: /node_modules/,
        // 优先执行，其它的loader会等这个执行完成再执行。
        enforce: 'pre',
        loader: 'eslint-loader',
        options: {
          // 这里是自动修复错误
          fix: true,
        },
      },
      {
        // js的兼容性处理
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
          presets: [
            [
              // 简单语法的兼容性，无法做promise等兼容。
              '@babel/preset-env',
              // 使用corejs做按需兼容。
              {
                useBuiltIns: 'usage',
                corejs: { version: 3 },
                targets: {
                  chrome: '60',
                  firefox: '50',
                },
              },
            ],
          ],
        },
      },
      {
        // 加载css中的图片资源
        // 这里使用的是es6语法
        test: /\.(jpg|png|gif)/,
        loader: 'url-loader',
        options: {
          // 图片大小如果小于8kb，则变成base64写入css中。
          limit: 8 * 1024,
          // 图片的名字，哈希值的前十位
          name: '[hash:10].[ext]',
          // 图片的输出路径
          outputPath: 'imgs',
          // 关闭es6语法
          esModule: false,
        },
      },
      {
        // 这里处理html中的图片
        // 这里使用的是commonjs语法
        test: /\.html$/,
        loader: 'html-loader',
      },
      {
        // 这里处理其它文件
        exclude: /\.(js|css|less|html|jpg|png|gif)/,
        // 可以复制粘贴文件到outputPaht中
        loader: 'file-loader',
        options: {
          outputPath: 'media',
        },
      },
    ],
  },
  plugins: [
    // 处理html文件，但是无法处理html中的 文件。
    new HtmlWebpackPlugin({
      template: resolve(__dirname, './src/index.html'),
      // 压缩html文件
      minify: {
        // 这里去除空格
        collapseWhitespace: true,
        // 这里去除注释
        removeComments: true,
      },
    }),
    new MiniCssExtractPlugin({
      // 重命名输出的文件
      filename: 'css/built.css',
    }),
    // 压缩css
    new OptimizeCssAssetsPlugin(),
  ],
  // 这里设置为production就会自动压缩js。
  mode: 'development',
}
